package com.hanock.sm.fork2d;

import android.graphics.Rect;
import android.graphics.RectF;


public abstract class NumberLabel extends Node {

	public static final int DIGIT_WIDTH_DEFAULT = 30;
	public static final int DIGIT_HEIGHT_DEFAULT = 60;
	
	private int number;
	private float digitWidth;
	private float digitHeight;
	private HorizontalAlign horizontalAlign;
	private VerticalAlign verticalAlign;
	
	private int minDigitCount;
	private int digitCount;
	
	private int resId;
	
	private Rect tempSrcRect;
	private RectF tempDesRect;
	
	
	public NumberLabel() {
		horizontalAlign = HorizontalAlign.CENTER;
		verticalAlign = VerticalAlign.TOP;
		digitWidth = DIGIT_WIDTH_DEFAULT;
		digitHeight = DIGIT_HEIGHT_DEFAULT;
		
		minDigitCount = 1;
		
		tempSrcRect = new Rect();
		tempDesRect = new RectF();
		
		setNumber(0);
	}

	@Override
	protected void draw(Canvas canvas) {
		super.draw(canvas);
		
		if (resId == 0)
			return;
		
		int forwardZeroCount = Math.max(0, minDigitCount - digitCount);
		
		for (int i = 0; i < forwardZeroCount; i++){
			getNumberSrcRect(0, tempSrcRect);
			getDesRect(-(i+1), tempDesRect);
			canvas.drawImage(tempSrcRect, tempDesRect, resId);
		}
		
		for (int i = 0; i < digitCount; i++){
			getSrcRect(i, tempSrcRect);
			getDesRect(i, tempDesRect);
			canvas.drawImage(tempSrcRect, tempDesRect, resId);
		}
	}
	
	/**
	 * @param num 0~9
	 */
	protected abstract void getNumberSrcRect(int num, Rect rect);
	
	public void getSrcRect(int index, Rect rect){

		//
		getNumberSrcRect(getDigit(index), rect);
	}
	
	public void getDesRect(int index, RectF rect){
		
		int forwardZeroCount = Math.max(0, minDigitCount - digitCount);
		float totalWidth = Math.max(minDigitCount, digitCount)*digitWidth;
			
		
		// calc rect, assuming align is LEFT
		rect.left = (int)(getX() + (index + forwardZeroCount)*digitWidth);
		rect.right = rect.left + digitWidth;
		rect.bottom = (int)getY();
		rect.top = rect.bottom + digitHeight;
		
		// apply align
		switch (horizontalAlign){
		case CENTER:
			rect.left -= totalWidth/2;
			rect.right = rect.left + digitWidth;
			break;
			
		case RIGHT:
			rect.left -= totalWidth;
			rect.right = rect.left + digitWidth;
			break;
		}
		
		switch (verticalAlign){
		case CENTER:
			rect.bottom -= digitHeight/2;
			rect.top = rect.bottom + digitHeight;
			break;
			
		case TOP:
			rect.bottom -= digitHeight;
			rect.top = rect.bottom + digitHeight;
			break;
		}
	}
	
	private int getDigit(int index){
		
		int n = (int)Math.pow(10, digitCount - 1 - index);
		
		return number / n % 10;
	}
	
	public HorizontalAlign getHorizontalAlign(){
		return horizontalAlign;
	}

	public void setHorizontalAlign(HorizontalAlign align){
		this.horizontalAlign = align;
	}
	
	public VerticalAlign getVerticalAlign() {
		return verticalAlign;
	}

	public void setVerticalAlign(VerticalAlign verticalAlign) {
		this.verticalAlign = verticalAlign;
	}

	public int getResId() {
		return resId;
	}
	
	public void setResId(int resId) {
		this.resId = resId;
	}
	
	public int calculateDigitCount(int n){
		
		if (n < 0)
			n = -n;
		
		if (n == 0)
			return 1;
		
		return (int)Math.log10(n) + 1;
	}

	/**
	 * 
	 * @param number zero or positive integer
	 */
	public void setNumber(int number) {
		if (number < 0)
			throw new IllegalArgumentException("number is negative");
		
		this.number = number;
		this.digitCount = calculateDigitCount(number);
	}

	public void setMinDigitCount(int minDigitCount) {
		this.minDigitCount = minDigitCount;
	}
	
	public float getDigitWidth() {
		return digitWidth;
	}

	public void setDigitWidth(float digitWidth) {
		this.digitWidth = digitWidth;
	}

	public float getDigitHeight() {
		return digitHeight;
	}

	public void setDigitHeight(float digitHeight) {
		this.digitHeight = digitHeight;
	}

	public int getDigitCount() {
		return digitCount;
	}
}
